package com.xnyzc.lhy.finance.service.impl.wallet;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.DateUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.common.util.TokenUtil;
import com.xnyzc.lhy.finance.config.AlipayConfig;
import com.xnyzc.lhy.finance.entity.bank.OaDBindAlipay;
import com.xnyzc.lhy.finance.entity.bank.OaDBindBankCard;
import com.xnyzc.lhy.finance.entity.bank.OaDWithdrawalDetails;
import com.xnyzc.lhy.finance.entity.config.OaSysCashWithdrawalConfig;
import com.xnyzc.lhy.finance.entity.wallet.OaDWallet;
import com.xnyzc.lhy.finance.mapper.bank.OaDBindAlipayMapper;
import com.xnyzc.lhy.finance.mapper.bank.OaDBindBankCardMapper;
import com.xnyzc.lhy.finance.mapper.bank.OaDUserMapper;
import com.xnyzc.lhy.finance.mapper.bank.OaDWithdrawalDetailsMapper;
import com.xnyzc.lhy.finance.mapper.wallet.OaDWalletMapper;
import com.xnyzc.lhy.finance.params.dto.cashwithdrawal.OaDWithdrawalDetailsResults;
import com.xnyzc.lhy.finance.service.config.IOaSysCashWithdrawalConfigService;
import com.xnyzc.lhy.finance.service.fegin.oss.FeginOssService;
import com.xnyzc.lhy.finance.service.wallet.IOaDWalletService;
import com.xnyzc.lhy.mis.entity.user.OaDUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 司机钱包表 服务实现类
 * </p>
 *
 * @author cuixiaojian
 * @since 2019-10-16
 */
@Slf4j
@Service
public class OaDWalletServiceImpl extends ServiceImpl<OaDWalletMapper, OaDWallet> implements IOaDWalletService {

    @Autowired
    private OaDWalletMapper oaDWalletMapper;

    @Autowired
    private OaDBindBankCardMapper oaDBindBankCardMapper;

    @Autowired
    private OaDBindAlipayMapper oaDBindAlipayMapper;

    @Autowired
    private OaDWithdrawalDetailsMapper oaDWithdrawalDetailsMapper;

    @Autowired
    private IOaSysCashWithdrawalConfigService iOaSysCashWithdrawalConfigService;

    @Autowired
    private FeginOssService feginOssService;

    @Autowired
    private OaDUserMapper oaDUserMapper;

    /**
     * 获取司机钱包信息
     *
     * @param driverId 司机ID
     * @return Object
     */
    @Override
    public Rv getDriverWalletInfo(Long driverId) {
        if (CheckUtil.objIsEmpty(driverId)) {
            throw PangException.create(EErrorCode.missingArg);
        }
        OaDWallet oaDWallet = null;
        try {
            QueryWrapper<OaDBindBankCard> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(OaDBindBankCard.DRIVER_ID,driverId);
            //Integer count = oaDBindBankCardMapper.checkBankCardBindStatus(driverId);
            Integer count = oaDBindBankCardMapper.selectCount(queryWrapper);
            oaDWallet = oaDWalletMapper.queryDriverWalletInfo(driverId, count);
        } catch (TooManyResultsException e) {
            log.error(e.getMessage());
            log.error("ID为：{}的司机，发现两个钱包信息，请立刻移除一个", driverId);
            throw PangException.create(EErrorCode.walletExistTwo);
        }
        if (CheckUtil.objIsEmpty(oaDWallet)) {
            throw PangException.create(EErrorCode.unWalletInfo);
        }
        if (CheckUtil.objIsNotEmpty(oaDWallet.getBankCardNumber())) {
            // 截取银行卡后四位返回
            String bankCardNumber = oaDWallet.getBankCardNumber();
            oaDWallet.setBankCardNumber(bankCardNumber.substring(bankCardNumber.length() - 4));
        }

        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("frozenBalance", oaDWallet.getFrozenBalance().toString());
        resultMap.put("walletBalance", String.valueOf((oaDWallet.getFrozenBalance().add(oaDWallet.getCashBalance())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()));
        resultMap.put("cashBalance", oaDWallet.getCashBalance().toString());
        resultMap.put("bankCardNumber", oaDWallet.getBankCardNumber());

        if (CheckUtil.objIsNotEmpty(oaDWallet.getBankIcon())) {
            resultMap.put("bankCardStatus", "1");
            try {
                Map<String, String> fileMap = (Map<String, String>) feginOssService.getFileUrl(Long.parseLong(oaDWallet.getBankIcon())).getData();
                resultMap.put("bankIcon", fileMap.get("fileUrl"));
            } catch (Exception e) {
                resultMap.put("bankIcon", "");
            }
        } else {
            resultMap.put("bankIcon", "");
            resultMap.put("bankCardStatus", "0");
        }
        OaSysCashWithdrawalConfig config = iOaSysCashWithdrawalConfigService.getCashWithdrawalConfig(driverId);
        if (CheckUtil.objIsNotEmpty(config)) {
            Integer freezePeriod = config.getFreezePeriod();
            String frozenText = oaDBindBankCardMapper.getType("feeze_config_comment").get("label");
            StringBuilder stringBuilder = new StringBuilder(frozenText);
            Integer indexX = frozenText.indexOf('X');
            // Integer indexY = frozenText.indexOf("Y");
            Integer indexZ = frozenText.indexOf('Z');
            if (indexX != -1) {
                stringBuilder.replace(indexX, indexX + 1, freezePeriod.toString());
            }
//            if (indexY != -1) {
//                stringBuilder.replace(indexY, indexY + 1, freezePeriod.toString());
//            }
            if (indexZ != -1) {
                stringBuilder.replace(indexZ, indexZ + 1, freezePeriod.toString());
            }
            log.info(stringBuilder.toString());
            resultMap.put("feezeConfigComment", stringBuilder.toString());
        } else {
            resultMap.put("feezeConfigComment", "");
        }
        resultMap.put("walletConfigComment", oaDBindBankCardMapper.getType("wallet_config_comment").get("label"));

        return Rv.wrap(resultMap);
    }

    @Override
    public Rv getWithdrawalAndAlipayState(Long driverId) {
        if (CheckUtil.objIsEmpty(driverId)) {
            throw PangException.create(EErrorCode.missingArg);
        }
        Calendar calendar = Calendar.getInstance();
        // 获取当前星期几:注意老外的第一天是从星期日开始的
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("alipayNumber",EErrorCode.alipayNoBind.getDesc());
        jsonObject.put("alipayBindState",0);
        jsonObject.put("alipayBindDesc",EErrorCode.alipayNoBind.getDesc());
        jsonObject.put("withdrawalState",0);
        jsonObject.put("withdrawalDesc",null);
        jsonObject.put("alipayNickName",null);
        //获取司机绑定支付宝状态
        QueryWrapper<OaDBindAlipay> alipayQueryWrapper = new QueryWrapper<>();
        alipayQueryWrapper.eq(OaDBindAlipay.DRIVER_ID,driverId);
        alipayQueryWrapper.eq(OaDBindAlipay.IS_USED,1);//使用状态
        alipayQueryWrapper.eq(OaDBindAlipay.DELETED,0);//使用状态
        Date lastWithdrawalDate = null;
        try{//这里可以会有俩个数据
            OaDBindAlipay oaDBindAlipay = oaDBindAlipayMapper.selectOne(alipayQueryWrapper);
            if(CheckUtil.objIsNotEmpty(oaDBindAlipay)){
                jsonObject.put("alipayNumber",oaDBindAlipay.getAlipayNumber());
                jsonObject.put("alipayBindState",1);
                jsonObject.put("alipayBindDesc","绑定支付宝成功");
                jsonObject.put("alipayNickName",oaDBindAlipay.getAlipayNickName());
                lastWithdrawalDate = oaDBindAlipay.getWithdrawalTime();
            }
        }catch (Exception e){
            return Rv.error(EErrorCode.dataNoIsOne);
        }
        //获取司机最后一次提现的时间戳
        long lastWithdrawalTime = 0;
        if(lastWithdrawalDate != null){
            lastWithdrawalTime = lastWithdrawalDate.getTime();
        }
        //获取本周一的时间戳
        long mondayTime = DateUtil.getMondayTime();
        //获取本周日的时间戳
        long sundayTime = DateUtil.getSundayTime();

        if(weekDay == 3){//是否星期二
            jsonObject.put("withdrawalState",1);
            jsonObject.put("withdrawalDesc",EErrorCode.platformWithdrawal.getDesc());
            if(mondayTime <= lastWithdrawalTime && lastWithdrawalTime <= sundayTime){//判断是否重复提现申请
                jsonObject.put("withdrawalState",0);
                jsonObject.put("withdrawalDesc",EErrorCode.platformNoWithdrawalByWeek.getDesc());
            }
        }else {
            jsonObject.put("withdrawalState",0);
            jsonObject.put("withdrawalDesc",EErrorCode.platformNoWithdrawal.getDesc());
        }


        return Rv.wrap(jsonObject);
    }

    @Override
    public Rv getDriverBindAlipay(Long driverId,String tokenCode) {
        if (CheckUtil.objIsEmpty(driverId) || CheckUtil.objIsEmpty(tokenCode)) {
            return Rv.error(EErrorCode.missingArg);
        }
        //查看是否已存在
        QueryWrapper<OaDBindAlipay> oaDBindAlipayQueryWrapper = new QueryWrapper<>();
        oaDBindAlipayQueryWrapper.eq(OaDBindAlipay.DRIVER_ID,driverId);
        List<OaDBindAlipay> oaDBindAlipayList = oaDBindAlipayMapper.selectList(oaDBindAlipayQueryWrapper);
        if(oaDBindAlipayList.size() > 0){
            return Rv.error(EErrorCode.alipayRepeatBind);
        }
        //获取支付宝会员信息
        String alipayUserInfoAll = AlipayConfig.getAlipayUserIdAndAccessToken(tokenCode);
        if(CheckUtil.objIsEmpty(alipayUserInfoAll)){
            return Rv.error(EErrorCode.alipayCreateFail);
        }
        String[] alipayUserInfo = alipayUserInfoAll.split(",");
        //验证司机是否存在
        OaDUser oaDUser = oaDUserMapper.selectById(driverId);
        if(CheckUtil.objIsEmpty(oaDUser)){
            return Rv.error(EErrorCode.notFoundDriverInfo);
        }
        //保存司机绑定支付宝的信息
        OaDBindAlipay oaDBindAlipay = new OaDBindAlipay();
        oaDBindAlipay.setAlipayId(IDUtil.nextId());
        oaDBindAlipay.setDriverId(driverId);
        oaDBindAlipay.setAlipayNumber("");
        oaDBindAlipay.setAlipayName("");
        oaDBindAlipay.setAlipayPhone("");
        oaDBindAlipay.setIsUsed(1);//默认使用
        oaDBindAlipay.setDeleted(0);
        oaDBindAlipay.setCreateUser(driverId);
        oaDBindAlipay.setUpdateUser(driverId);
        oaDBindAlipay.setCreateTime(new Date());
        oaDBindAlipay.setUpdateTime(new Date());
        oaDBindAlipay.setAlipayUserId(alipayUserInfo[0]);
        oaDBindAlipay.setAlipayNickName(alipayUserInfo[1]);

        int size = oaDBindAlipayMapper.insert(oaDBindAlipay);
        if(size <= 0){
            return Rv.error(EErrorCode.alipayBindfail);
        }
        return Rv.wrap();
    }

    @Override
    public Rv applyDriverWithdrawal(OaDWithdrawalDetails param) {
        Long driverId = TokenUtil.getTokenUserId();
        if (CheckUtil.objIsEmpty(driverId) || CheckUtil.objIsEmpty(param.getApplyMoney())
                || CheckUtil.objIsEmpty(param.getDriverName()) || CheckUtil.objIsEmpty(param.getCityId())) {
            return Rv.error(EErrorCode.missingArg);
        }
        Date now = new Date();
        long curTime = now.getTime();

        OaDBindAlipay oaDBindAlipay;
        OaDWallet oaDWallet;
        BigDecimal applyMoney;
        try{//这里可以会有俩个数据

            //验证司机钱包 可提现金额是否足够
            QueryWrapper<OaDWallet> oaDWalletQueryWrapper = new QueryWrapper<>();
            oaDWalletQueryWrapper.eq(OaDWallet.DRIVER_ID,driverId);
            oaDWallet = oaDWalletMapper.selectOne(oaDWalletQueryWrapper);
            if (CheckUtil.objIsEmpty(oaDWallet)){
                return Rv.error(EErrorCode.unWallet);
            }
            //钱包余额
            BigDecimal walletBalance = oaDWallet.getWalletBalance();
            //钱包可提现金额
            BigDecimal cashBalance = oaDWallet.getCashBalance();
            //申请金额
            applyMoney = new BigDecimal(param.getApplyMoney());
            if(applyMoney.compareTo(new BigDecimal(0.1)) == -1){
                return Rv.error(EErrorCode.moneyTooSmall);
            }
            //result = -1---表示a小于b  result = 0---表示a等于b;  result = 1--表示a大于b;
            if(walletBalance.compareTo(applyMoney) == -1){
                return Rv.error(EErrorCode.insufficientSpace);
            }
            //验证司机是否绑定支付宝
            QueryWrapper<OaDBindAlipay> alipayQueryWrapper = new QueryWrapper<>();
            alipayQueryWrapper.eq(OaDBindAlipay.DRIVER_ID,driverId);
            alipayQueryWrapper.eq(OaDBindAlipay.IS_USED,1);//使用状态

            oaDBindAlipay = oaDBindAlipayMapper.selectOne(alipayQueryWrapper);
            if(CheckUtil.objIsEmpty(oaDBindAlipay)){
                return Rv.error(EErrorCode.alipayNoBind);
            }
        } catch (Exception e){
            return Rv.error(EErrorCode.dataNoIsOne);
        }
        Calendar calendar = Calendar.getInstance();
        // 获取当前星期几:注意老外的第一天是从星期日开始的
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        //获取本周一的时间戳
        long mondayTime = DateUtil.getMondayTime();
        //获取本周日的时间戳
        long sundayTime = DateUtil.getSundayTime();

            if(weekDay == 3){//是否星期二
                if(mondayTime <= curTime && curTime <= sundayTime){//判断是否重复提现申请
                    Rv.error(EErrorCode.platformNoWithdrawalByWeek);
                }
                OaDWithdrawalDetails oaDWithdrawalDetails = new OaDWithdrawalDetails();

                oaDWithdrawalDetails.setWithdrawalDetailsId(IDUtil.nextId());
                oaDWithdrawalDetails.setDriverId(oaDBindAlipay.getDriverId());
                oaDWithdrawalDetails.setDriverName(param.getDriverName());
                oaDWithdrawalDetails.setAlipayNumber(oaDBindAlipay.getAlipayUserId());
                oaDWithdrawalDetails.setAlipayName(oaDBindAlipay.getAlipayName());
                oaDWithdrawalDetails.setAlipayPhone(oaDBindAlipay.getAlipayPhone());
                oaDWithdrawalDetails.setApplyTime(now);
                oaDWithdrawalDetails.setApplyMoney(param.getApplyMoney());
                oaDWithdrawalDetails.setWithdrawalType("alipay");
                oaDWithdrawalDetails.setApplyState(1);//默认处理状态
                oaDWithdrawalDetails.setCityId(param.getCityId());
                oaDWithdrawalDetails.setCityName(param.getCityName());
                //创建申请提现信息表
                oaDWithdrawalDetailsMapper.insert(oaDWithdrawalDetails);

                //重置提现时间
                oaDBindAlipay.setWithdrawalTime(now);
                oaDBindAlipayMapper.updateById(oaDBindAlipay);

                //更新司机钱包余额
                BigDecimal newWalletBalance = oaDWallet.getWalletBalance().subtract(applyMoney);
                oaDWallet.setWalletBalance(newWalletBalance);//更新钱包余额
                //result = -1---表示a小于b  result = 0---表示a等于b;  result = 1--表示a大于b;
                BigDecimal cashBalance = oaDWallet.getCashBalance();//可提现金额
                BigDecimal frozenBalance = oaDWallet.getFrozenBalance();//冻结金额
                if(applyMoney.compareTo(cashBalance) == -1){
                    oaDWallet.setCashBalance(cashBalance.subtract(applyMoney));
                }else {
                    oaDWallet.setCashBalance(new BigDecimal(0));
                    BigDecimal newCashBalance = applyMoney.subtract(cashBalance);
                    oaDWallet.setFrozenBalance(frozenBalance.subtract(newCashBalance));
                }
                BigDecimal cashTotal = oaDWallet.getCashTotal();//历史提现总金额
                oaDWallet.setCashTotal(cashTotal.add(applyMoney));//加历史提现总金额
                oaDWallet.setCashingBalance(applyMoney);//加提现中金额
                oaDWalletMapper.updateById(oaDWallet);

            }else {
                Rv.error(EErrorCode.platformNoWithdrawal);
            }


        return Rv.wrap();
    }

    @Override
    public Rv getDriverWithdrawalDetails(OaDWithdrawalDetailsResults param) {
        Long driverId = TokenUtil.getTokenUserId();
        if (CheckUtil.objIsEmpty(driverId) || CheckUtil.objIsEmpty(param.getCurrent())
                || CheckUtil.objIsEmpty(param.getSize())) {
            return Rv.error(EErrorCode.missingArg);
        }
        IPage<OaDWithdrawalDetails> iPage = new Page<>();
        iPage.setCurrent(param.getCurrent());
        iPage.setSize(param.getSize());

        QueryWrapper<OaDWithdrawalDetails> oaDWithdrawalDetailsQueryWrapper = new QueryWrapper<>();
        oaDWithdrawalDetailsQueryWrapper.eq(OaDWithdrawalDetails.DRIVER_ID,driverId);
        oaDWithdrawalDetailsQueryWrapper.orderByDesc(OaDWithdrawalDetails.APPLY_TIME);

        IPage<OaDWithdrawalDetails> iPageList = oaDWithdrawalDetailsMapper.selectPage(iPage,oaDWithdrawalDetailsQueryWrapper);
        if (CheckUtil.objIsEmpty(iPageList)){
            return Rv.error(EErrorCode.infoIsNull);
        }
        return Rv.wrap(iPageList);
    }

}
